package control;

import java.util.List;

import entidades.Hoja;

import auxiliares.Transformer;

/**
 * Clase de Control: Clase para analizar los String, de tener alguna referecnia a una hoja, se quita y se remplaza por su correspondiente valor.
 *
 * @author  Grupo N11
 * @author   Prinsich Bernz, Emilio J. A.
 * @author 	 Solia, Guillermo D.
 * @version  1.5
 */

public class Analizador {
	
	//Constructor---------------------------------------------------------------------------------
	/**
	 * Construnctor de la Clase.
	 */
	public Analizador(){}
	
	//Metodo Principal---------------------------------------------------------------------------------
	/**
	 * Obtine el valor de la referencia de una hoja de terminada.
	 * @param dato
	 * 			String a analizar.
	 * @param hojas
	 * 			Listado de hojas.
	 * @param nHoja
	 * 			Numero de hoja referencida.
	 * @param fila
	 * 			Fila de la celda referencida.
	 * @param columna
	 * 			Columna de la celda refereciada.
	 * @param lista
	 * 			Lista donde se almacenan la hoja, fila y columna de las celdas escuchas
	 * @param tipo
	 * 			Tipo de funcion que llama a analizador (SUMA,SI o CALCULAR)
	 * @return str;
	 * 			String sin referencias a hojas.
	 * @throws ErrorSintaxis
	 * 			En caso de haber error de sintaxis dipara la excepcion.
	 */
	public static String Analizar(String dato, List<Hoja> hojas, int nHoja, int fila, int columna, List<Integer> lista,int tipo)throws ErrorSintaxis{
		String tmp = "";
		String str = new String();
		try{
			//Busco referencias a celdas con HOJA ej: HOJA1!A1
			for(int i = 0; i < dato.length(); i++){
				//encentro una hoja
				if(dato.charAt(i) == 'H'){

					if(dato.substring(i, i+4).equals("HOJA")){

						String nroHoja = "";
						String celda = "";
						int j = 4;
						//Almaceno el numero de hoja
						while(dato.charAt(i + j) != '!'){
							nroHoja = nroHoja + dato.charAt(i + j);
							j++;
						}
						j++;//paso por alto el !
						//Almaceno el id IdCelda
						while(dato.charAt(i + j) != '#' && !(esOperador(dato.charAt(i + j),tipo))){
							celda = celda + dato.charAt(i + j);
							j++;
						}
						//convierto el nro de hoja de String a int
						int k = Integer.parseInt(nroHoja) - 1;
						//convierto la celda en fila y columna
						Transformer optimus = new Transformer(celda);
						String tmp2;
						//obtengo el dato y sino asigno error
						if(optimus.getFila() >= 0 &&  optimus.getColumna() >= 0){
							tmp2 = hojas.get(k).getDato(optimus.getFila(), optimus.getColumna());
							tmp = tmp + tmp2;
							i = i + j - 1;
							lista.add(k);
							lista.add(optimus.getFila());
							lista.add(optimus.getColumna());
						}
						else{throw new ErrorSintaxis("#VALOR","Seleccione una Celda");}
					}
					//la H era un simple char continuo
					else
						tmp = tmp + dato.charAt(i);
				}
				//no es una hoja continuo
				else
					tmp = tmp + dato.charAt(i);
			}
			//FIN //Busco referencias a celdas con HOJA ej: HOJA1!A1
			
			//Busco referencia simples a celdas
			String cadenaSinHojas = tmp;
			str = "";
			
			for(int i = 0; i < cadenaSinHojas.length(); i++){
				String tmp3 = "";
					while(cadenaSinHojas.charAt(i) != '#' && !(esOperador(cadenaSinHojas.charAt(i),tipo))){
						tmp3 = tmp3 + cadenaSinHojas.charAt(i);
						i++;
					}
					
					//Transforma la celda a su correspondiente coordenada
					Transformer tr = new Transformer(tmp3);
					int f = tr.getFila();
					int c = tr.getColumna();
					if (f >= 0 && c >= 0){
						tmp3 = (hojas.get(nHoja)).getDato(f,c);
						(hojas.get(nHoja)).getCelda(f,c).setListaSujeto((hojas.get(nHoja)).getCelda(fila,columna));
						str = str + tmp3+ cadenaSinHojas.charAt(i);
						
					//Almaceno hoja, fila y columna de las celdas escuchas	
						lista.add(nHoja);
						lista.add(f);
						lista.add(c);
					}
					else str = str + tmp3+ cadenaSinHojas.charAt(i);
				//	else{ throw new ErrorSintaxis("#VALOR","Referencia a celda invalida");}
		//		} else str = str + cadenaSinHojas.charAt(i);
			}
			//FIN Busco referencia simples a celdas
		}catch (Exception e1) { //capturo el error del Integer.parseInt()
			hojas.get(nHoja).setDato("#VALOR", fila, columna);
		}
		return str;
	}
	
	//Metodo Auxiliares---------------------------------------------------------------------------------
	
	 /* Compara el caracter y retrona true o false si es igual a algun signo.
	 * @param charAt
	 * 			Caracter a analizar
	 * @return boolean
	 * 			Resultado del analisis.
	 */
	private static boolean esOperador(char charAt,int tipo) {
		//Para funcion calcular
		if(tipo == 0){
			if(charAt == '+')
				return true;
			else if(charAt == '-')
				return true;
			else if(charAt == '*')
				return true;
			else if(charAt == '/')
				return true;
			else if(charAt == '(')
				return true;
			else if(charAt == ')')
				return true;
		}
		//Para funcion SI
		else if(tipo == 1){
			if(charAt == '=')
				return true;
			else if(charAt == ';')
				return true;
			else if(charAt == ')')
				return true;
		}
		//Para funcion SUMA
		else if(tipo == 2){
			if(charAt == ':')
				return true;
			else if(charAt == ',')
				return true;
			else if(charAt == ')')
				return true;
		}
		return false;
	}
	

}
